<template>
  <div class="app-container">
    <!-- 仪表盘标题和刷新按钮 -->
    <div class="header-section">
      <div class="header-left">
        <h2>广电用户数据分析仪表盘</h2>
        <div v-if="lastRefreshTime" class="last-refresh-time">
          最后更新: {{ lastRefreshTime }}
        </div>
      </div>
      <div class="header-right">
        <el-button type="success" icon="el-icon-upload" @click="importCsvData" style="margin-right: 15px;">
          导入CSV数据
        </el-button>
        <el-switch
          v-model="autoRefresh"
          active-text="自动刷新"
          inactive-text="手动刷新"
          @change="toggleAutoRefresh"
          style="margin-right: 15px;"
        />
        <el-select
          v-model="refreshInterval"
          placeholder="刷新间隔"
          style="width: 120px; margin-right: 15px;"
          @change="setRefreshInterval"
        >
          <el-option :value="30" label="30秒" />
          <el-option :value="60" label="1分钟" />
          <el-option :value="300" label="5分钟" />
          <el-option :value="600" label="10分钟" />
        </el-select>
        <el-button type="primary" icon="el-icon-refresh" @click="refreshData" :loading="loading">
          {{ autoRefresh ? `下次刷新(${remainingTime}s)` : '刷新数据' }}
        </el-button>
      </div>
    </div>

    <!-- 指标卡区域 -->
    <el-row :gutter="20" class="metrics-section">
      <el-col :xs="12" :sm="12" :md="8" :lg="6" :xl="6">
        <div class="metric-card total-users">
          <div class="metric-icon">
            <i class="el-icon-user-solid"></i>
          </div>
          <div class="metric-content">
            <div class="metric-value">{{ dashboardData.totalUsers || 0 }}</div>
            <div class="metric-label">总用户数</div>
          </div>
        </div>
      </el-col>
      <el-col :xs="12" :sm="12" :md="8" :lg="6" :xl="6">
        <div class="metric-card heavy-users">
          <div class="metric-icon">
            <i class="el-icon-sold-out"></i>
          </div>
          <div class="metric-content">
            <div class="metric-value">{{ dashboardData.heavyUsers || 0 }}</div>
            <div class="metric-label">重度用户</div>
          </div>
        </div>
      </el-col>
      <el-col :xs="12" :sm="12" :md="8" :lg="6" :xl="6">
        <div class="metric-card loyal-users">
          <div class="metric-icon">
            <i class="el-icon-star-on"></i>
          </div>
          <div class="metric-content">
            <div class="metric-value">{{ dashboardData.loyalUsers || 0 }}</div>
            <div class="metric-label">忠诚用户</div>
          </div>
        </div>
      </el-col>
      <el-col :xs="12" :sm="12" :md="8" :lg="6" :xl="6">
        <div class="metric-card broadband-users">
          <div class="metric-icon">
            <i class="el-icon-wifi"></i>
          </div>
          <div class="metric-content">
            <div class="metric-value">{{ dashboardData.broadbandUsers || 0 }}</div>
            <div class="metric-label">宽带用户</div>
          </div>
        </div>
      </el-col>
    </el-row>

    <!-- 图表区域第一行 -->
    <el-row :gutter="20" class="charts-section">
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <div class="chart-card">
          <div class="chart-header">
            <h3>电视消费水平分布</h3>
          </div>
          <div class="chart-content">
            <div id="consumptionChart" class="chart"></div>
          </div>
        </div>
      </el-col>
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <div class="chart-card">
          <div class="chart-header">
            <h3>用户标签分布</h3>
          </div>
          <div class="chart-content">
            <div id="tagDistributionChart" class="chart"></div>
          </div>
        </div>
      </el-col>
    </el-row>

    <!-- 图表区域第二行 -->
    <el-row :gutter="20" class="charts-section">
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <div class="chart-card">
          <div class="chart-header">
            <h3>渗透率分析</h3>
          </div>
          <div class="chart-content">
            <div id="penetrationChart" class="chart"></div>
          </div>
        </div>
      </el-col>
      <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
        <div class="chart-card">
          <div class="chart-header">
            <h3>服务品牌分布</h3>
          </div>
          <div class="chart-content">
            <div id="brandChart" class="chart"></div>
          </div>
        </div>
      </el-col>
    </el-row>

    <!-- 最近数据表格 -->
    <div class="recent-data-section">
      <div class="section-header">
        <h3>最近用户数据</h3>
      </div>
      <el-table :data="recentUsers" stripe style="width: 100%">
        <el-table-column prop="terminalNo" label="地址编号" width="180" />
        <el-table-column prop="phoneNo" label="用户编号" width="180" />
        <el-table-column prop="smName" label="品牌名称" width="120" />
        <el-table-column prop="isHeavyUser" label="重度用户" width="100">
          <template slot-scope="scope">
            <el-tag :type="scope.row.isHeavyUser === '是' ? 'warning' : 'info'">
              {{ scope.row.isHeavyUser }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="tvConsumptionLevel" label="电视消费" width="100">
          <template slot-scope="scope">
            <el-tag :type="getConsumptionLevelType(scope.row.tvConsumptionLevel)">
              {{ scope.row.tvConsumptionLevel }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="createTime" label="创建时间" width="180" />
      </el-table>
    </div>

    <!-- 加载遮罩 -->
    <div class="loading-mask" v-if="loading">
      <el-loading-spinner></el-loading-spinner>
      <p>加载中...</p>
    </div>
  </div>
</template>

<script>
import { getDashboardData, importGuangDianUserFromCsv } from "@/api/system/guangdian";
import * as echarts from "echarts";

export default {
  name: "GuangDianDashboard",
  data() {
    return {
      loading: false,
      autoRefresh: true,
      refreshInterval: 60, // 默认60秒刷新一次
      remainingTime: 60,
      refreshTimer: null,
      dashboardData: {
        totalUsers: 0,
        heavyUsers: 0,
        loyalUsers: 0,
        highTvConsumption: 0,
        mediumTvConsumption: 0,
        lowTvConsumption: 0,
        broadbandUsers: 0,
        // 添加默认数据以确保图表正确显示
        tagDistribution: {
          heavyUser: 1500,
          loyalUser: 2500,
          broadbandUser: 3000,
          regularUser: 5000
        },
        penetrationRates: {
          broadband: 65,
          heavyUser: 45,
          loyalUser: 30
        },
        brandDistribution: {
          cableTv: 45,
          iptv: 30,
          ott: 15,
          others: 10
        }
      },
      recentUsers: [],
      charts: {},
      lastRefreshTime: ''
    };
  },
  mounted() {
      this.initDashboard();
      // 监听窗口大小变化，重新渲染图表
      window.addEventListener("resize", this.handleResize);
      // 启动自动刷新
      if (this.autoRefresh) {
        this.startAutoRefresh();
      }
    },
  beforeDestroy() {
      // 清理事件监听
      window.removeEventListener("resize", this.handleResize);
      // 销毁图表实例
      Object.values(this.charts).forEach(chart => {
        if (chart) {
          chart.dispose();
        }
      });
      // 清除定时器
      this.clearAutoRefresh();
    },
  methods: {
    /** 初始化仪表盘 */
    initDashboard() {
      this.loading = true;
      getDashboardData().then(response => {
        if (response.code === 200) {
          // 记录数据变化，用于动画效果
          const oldData = { ...this.dashboardData };
          // 合并数据，保留默认值以确保图表正常显示
          this.dashboardData = { ...this.dashboardData, ...(response.data || {}) };
          
          // 更新最后刷新时间
          this.lastRefreshTime = new Date().toLocaleString();
          
          // 获取最近用户数据
          this.fetchRecentUsers();
          
          // 延迟渲染图表，确保DOM已经渲染完成
          this.$nextTick(() => {
            this.initializeChartsWithCheck(oldData);
            this.loading = false;
          });
        } else {
          this.loading = false;
          this.$message.error("获取数据失败：" + (response.msg || ''));
          // 即使后端数据获取失败，也要初始化图表以显示默认数据
          this.$nextTick(() => {
            this.initializeChartsWithCheck({});
          });
        }
      }).catch((error) => {
        this.loading = false;
        this.$message.error("获取数据失败，请检查网络连接");
        console.error('Dashboard data fetch error:', error);
        // 网络错误时也要初始化图表
        this.$nextTick(() => {
          this.initializeChartsWithCheck({});
        });
      });
    },
    
    /** 安全地初始化或更新图表 */
    initializeChartsWithCheck(oldData) {
      // 检查是否已经初始化图表
      const needsInit = Object.keys(this.charts).length === 0;
      
      // 确保所有图表容器都已存在
      const chartIds = ['consumptionChart', 'tagDistributionChart', 'penetrationChart', 'brandChart'];
      const allElementsExist = chartIds.every(id => document.getElementById(id));
      
      // 预处理数据，确保数据格式正确
      this.preprocessDashboardData();
      
      if (allElementsExist) {
        if (needsInit) {
          this.initCharts();
        } else {
          // 确保oldData也经过预处理
          const processedOldData = this.preprocessDataForAnimation(oldData);
          this.updateChartsWithAnimation(processedOldData);
        }
      } else {
        // 如果DOM元素不存在，延迟重试
        console.warn('图表容器元素不存在，稍后重试初始化');
        setTimeout(() => {
          this.initializeChartsWithCheck(oldData);
        }, 200);
      }
    },
    
    /** 预处理仪表盘数据，确保数据格式正确 */
    preprocessDashboardData() {
      // 确保所有必要的数据字段都存在且类型正确
      const processField = (field, defaultValue = 0) => {
        const value = this.dashboardData[field];
        if (value === undefined || value === null || isNaN(Number(value))) {
          this.dashboardData[field] = defaultValue;
        } else {
          this.dashboardData[field] = Number(value);
        }
      };
      
      // 处理基础指标数据
      ['totalUsers', 'heavyUsers', 'loyalUsers', 'broadbandUsers', 
       'highTvConsumption', 'mediumTvConsumption', 'lowTvConsumption'].forEach(field => {
        processField(field);
      });
      
      // 确保嵌套对象存在
      if (!this.dashboardData.tagDistribution) {
        this.dashboardData.tagDistribution = {};
      }
      if (!this.dashboardData.penetrationRates) {
        this.dashboardData.penetrationRates = {};
      }
      if (!this.dashboardData.brandDistribution) {
        this.dashboardData.brandDistribution = {};
      }
      
      // 处理标签分布数据
      processField('tagDistribution.heavyUser', this.dashboardData.heavyUsers || 1500);
      processField('tagDistribution.loyalUser', this.dashboardData.loyalUsers || 2500);
      processField('tagDistribution.broadbandUser', this.dashboardData.broadbandUsers || 3000);
      
      // 计算普通用户数
      const total = this.dashboardData.totalUsers || 0;
      const heavy = this.dashboardData.tagDistribution.heavyUser || 0;
      const loyal = this.dashboardData.tagDistribution.loyalUser || 0;
      const broadband = this.dashboardData.tagDistribution.broadbandUser || 0;
      this.dashboardData.tagDistribution.regularUser = Math.max(0, total - heavy - loyal - broadband) || 5000;
      
      // 处理渗透率数据
      processField('penetrationRates.broadband', 65);
      processField('penetrationRates.heavyUser', 45);
      processField('penetrationRates.loyalUser', 30);
      
      // 处理品牌分布数据
      processField('brandDistribution.cableTv', 45);
      processField('brandDistribution.iptv', 30);
      processField('brandDistribution.ott', 15);
      processField('brandDistribution.others', 10);
      
      // 确保消费数据合理
      this.normalizeConsumptionData();
      
      // 确保所有百分比值在合理范围内
      this.constrainPercentageValues();
    },
    
    /** 归一化消费数据，确保数据合理 */
    normalizeConsumptionData() {
      const high = this.dashboardData.highTvConsumption || 0;
      const medium = this.dashboardData.mediumTvConsumption || 0;
      const low = this.dashboardData.lowTvConsumption || 0;
      const totalConsumption = high + medium + low;
      
      // 如果所有消费数据都为0，设置默认值
      if (totalConsumption === 0) {
        this.dashboardData.highTvConsumption = 3000;
        this.dashboardData.mediumTvConsumption = 5000;
        this.dashboardData.lowTvConsumption = 7000;
      }
    },
    
    /** 确保百分比值在0-100之间 */
    constrainPercentageValues() {
      Object.keys(this.dashboardData.penetrationRates || {}).forEach(key => {
        let value = this.dashboardData.penetrationRates[key];
        value = Math.max(0, Math.min(100, value || 0));
        this.dashboardData.penetrationRates[key] = value;
      });
    },
    
    /** 预处理动画数据 */
    preprocessDataForAnimation(oldData) {
      const processed = { ...oldData };
      
      // 确保必要的字段存在
      ['totalUsers', 'heavyUsers', 'loyalUsers', 'broadbandUsers', 
       'highTvConsumption', 'mediumTvConsumption', 'lowTvConsumption'].forEach(field => {
        if (processed[field] === undefined) {
          processed[field] = 0;
        }
      });
      
      return processed;
    },
    
    /** 导入CSV数据 */
    async importCsvData() {
      try {
        // 使用固定的CSV文件路径
        const filePath = 'c:\\Users\\Administrator\\RuoYi-Vue\\sql\\mediamatch_usermsg_first20000.csv';
        this.$confirm('确定要导入CSV数据吗？这将会导入大量数据，可能需要一些时间。', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(async () => {
          const loading = this.$loading({
            lock: true,
            text: '数据导入中，请稍候...',
            spinner: 'el-icon-loading',
            background: 'rgba(0, 0, 0, 0.7)'
          });
          
          try {
            // 先测试导入2000条数据
            const testResponse = await importGuangDianUserFromCsv(filePath, 2000);
            if (testResponse.code === 200) {
              this.$message.success('测试数据导入成功，共导入' + testResponse.data + '条记录');
              this.refreshData();
              
              // 询问是否继续导入剩余全部数据
              this.$confirm('测试数据导入成功，是否继续导入剩余全部数据？', '提示', {
                confirmButtonText: '继续导入',
                cancelButtonText: '取消',
                type: 'info'
              }).then(async () => {
                try {
                  // 导入全部数据（limit=0表示全部）
                  const fullResponse = await importGuangDianUserFromCsv(filePath, 0);
                  if (fullResponse.code === 200) {
                    this.$message.success('全部数据导入成功，共导入' + fullResponse.data + '条记录');
                    this.refreshData();
                  } else {
                    this.$message.error('导入剩余数据失败：' + (fullResponse.msg || '未知错误'));
                  }
                } catch (error) {
                  this.$message.error('导入剩余数据失败：' + (error.message || '未知错误'));
                } finally {
                  loading.close();
                }
              }).catch(() => {
                this.$message.info('已取消导入剩余数据');
                loading.close();
              });
            } else {
              this.$message.error('测试数据导入失败：' + (testResponse.msg || '未知错误'));
              loading.close();
            }
          } catch (error) {
            this.$message.error('导入失败：' + (error.message || '未知错误'));
            loading.close();
          }
        }).catch(() => {
          this.$message.info('已取消导入');
        });
      } catch (error) {
        this.$message.error('操作失败：' + error.message);
      }
    },
    
    /**
     * 获取最近用户数据
     */
    fetchRecentUsers() {
      // 调用API获取最近用户数据
      this.$api.system.guangdian.getRecentUsers(10).then(response => {
        if (response.code === 200) {
          this.recentUsers = response.data || [];
        }
      }).catch(() => {
        // 如果获取失败，使用模拟数据
        this.recentUsers = this.getMockRecentUsers();
      });
    },
    
    /**
     * 获取模拟的最近用户数据
     */
    getMockRecentUsers() {
      const now = new Date();
      return [
        {
          terminalNo: "T001",
          phoneNo: "U001",
          smName: "有线电视",
          isHeavyUser: "是",
          tvConsumptionLevel: "高",
          createTime: new Date(now - 5 * 60 * 1000).toLocaleString()
        },
        {
          terminalNo: "T002",
          phoneNo: "U002",
          smName: "IPTV",
          isHeavyUser: "否",
          tvConsumptionLevel: "中",
          createTime: new Date(now - 10 * 60 * 1000).toLocaleString()
        },
        {
          terminalNo: "T003",
          phoneNo: "U003",
          smName: "有线电视",
          isHeavyUser: "否",
          tvConsumptionLevel: "低",
          createTime: new Date(now - 15 * 60 * 1000).toLocaleString()
        }
      ];
    },

    /**
     * 刷新数据
     */
    refreshData() {
      // 重置倒计时
      if (this.autoRefresh) {
        this.remainingTime = this.refreshInterval;
      }
      
      this.loading = true;
      getDashboardData().then(response => {
        if (response.code === 200) {
          // 记录数据变化，用于动画效果
          const oldData = { ...this.dashboardData };
          this.dashboardData = response.data || {};
          
          // 更新最后刷新时间
          this.lastRefreshTime = new Date().toLocaleString();
          
          // 更新图表数据，并添加动画效果
          this.updateChartsWithAnimation(oldData);
          
          // 更新最近用户数据
          this.fetchRecentUsers();
          
          this.loading = false;
          this.$message.success("数据刷新成功");
        } else {
          this.loading = false;
          this.$message.error("刷新数据失败：" + (response.msg || ''));
        }
      }).catch((error) => {
        this.loading = false;
        this.$message.error("刷新数据失败，请检查网络连接");
        console.error('Dashboard data refresh error:', error);
      });
    },
    
    /**
     * 启动自动刷新
     */
    startAutoRefresh() {
      if (this.refreshTimer) {
        clearInterval(this.refreshTimer);
      }
      
      this.remainingTime = this.refreshInterval;
      
      // 创建定时器
      this.refreshTimer = setInterval(() => {
        this.remainingTime--;
        if (this.remainingTime <= 0) {
          this.refreshData();
          this.remainingTime = this.refreshInterval;
        }
      }, 1000);
    },
    
    /**
     * 停止自动刷新
     */
    stopAutoRefresh() {
      this.clearAutoRefresh();
      this.autoRefresh = false;
    },
    
    /**
     * 清除自动刷新定时器
     */
    clearAutoRefresh() {
      if (this.refreshTimer) {
        clearInterval(this.refreshTimer);
        this.refreshTimer = null;
      }
    },
    
    /**
     * 切换自动刷新状态
     */
    toggleAutoRefresh() {
      this.autoRefresh = !this.autoRefresh;
      if (this.autoRefresh) {
        this.startAutoRefresh();
      } else {
        this.stopAutoRefresh();
      }
    },
    
    /**
     * 设置刷新间隔
     */
    setRefreshInterval(interval) {
      this.refreshInterval = interval;
      this.remainingTime = interval;
      if (this.autoRefresh) {
        this.startAutoRefresh();
      }
    },

    /** 初始化所有图表 */
    initCharts() {
      this.initConsumptionChart();
      this.initTagDistributionChart();
      this.initPenetrationChart();
      this.initBrandChart();
    },

    /** 初始化电视消费分布图表 */
    initConsumptionChart() {
      const chartDom = document.getElementById('consumptionChart');
      if (!chartDom) return;
      
      try {
        const chart = echarts.init(chartDom);
        this.charts.consumption = chart;
        
        // 使用渐变色提高视觉效果
        const highColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {offset: 0, color: '#ff6b6b'},
          {offset: 1, color: '#ee5a6f'}
        ]);
        const mediumColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {offset: 0, color: '#48dbfb'},
          {offset: 1, color: '#0abde3'}
        ]);
        const lowColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {offset: 0, color: '#54a0ff'},
          {offset: 1, color: '#0984e3'}
        ]);
        
        // 获取并确保数据有效
        const highValue = this.dashboardData.highTvConsumption || 0;
        const mediumValue = this.dashboardData.mediumTvConsumption || 0;
        const lowValue = this.dashboardData.lowTvConsumption || 0;
        const totalValue = highValue + mediumValue + lowValue;
        
        // 构建数据数组，添加空数据检查
        const data = [];
        if (highValue > 0) data.push({ value: highValue, name: '高消费', itemStyle: { color: highColor } });
        if (mediumValue > 0) data.push({ value: mediumValue, name: '中消费', itemStyle: { color: mediumColor } });
        if (lowValue > 0) data.push({ value: lowValue, name: '低消费', itemStyle: { color: lowColor } });
        
        // 如果没有有效数据，添加默认占位数据
        if (data.length === 0) {
          data.push({ value: 1, name: '暂无数据', itemStyle: { color: '#dcdfe6' } });
        }
        
        const option = {
          tooltip: {
            trigger: 'item',
            formatter: function(params) {
              const total = totalValue > 0 ? totalValue : 1;
              return `${params.seriesName}<br/>${params.name}: ${params.value} (${params.percent}%)<br/>占比分析：${(params.value/total*100).toFixed(1)}%`;
            },
            backgroundColor: 'rgba(0, 0, 0, 0.8)',
            borderColor: '#666',
            textStyle: { color: '#fff' }
          },
          legend: {
            orient: 'horizontal',
            bottom: 10,
            left: 'center',
            data: data.map(item => item.name),
            textStyle: {
              color: '#666',
              fontSize: 12
            }
          },
          color: [highColor, mediumColor, lowColor],
          series: [
            {
              name: '消费水平分布',
              type: 'pie',
              radius: ['35%', '70%'],
              center: ['50%', '45%'],
              avoidLabelOverlap: false,
              itemStyle: {
                borderRadius: 8,
                borderColor: '#fff',
                borderWidth: 2
              },
              label: {
                show: data.length === 1 && data[0].name === '暂无数据',
                position: 'center',
                formatter: '暂无数据',
                color: '#909399',
                fontSize: 16
              },
              emphasis: {
                label: {
                  show: true,
                  fontSize: '16',
                  fontWeight: 'bold',
                  color: '#333'
                },
                itemStyle: {
                  shadowBlur: 15,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.3)'
                }
              },
              labelLine: {
                show: false
              },
              data: data,
              // 添加动画配置
              animationDuration: 1000,
              animationEasing: 'cubicOut',
              animationDelay: function(idx) {
                return idx * 100;
              }
            }
          ]
        };
        
        chart.setOption(option);
      } catch (error) {
        console.error('初始化消费分布图表失败:', error);
      }
    },

    /** 初始化用户标签分布图表 */
    initTagDistributionChart() {
      const chartDom = document.getElementById('tagDistributionChart');
      if (!chartDom) return;

      try {
        const chart = echarts.init(chartDom);
        this.charts.tagDistribution = chart;

        // 处理数据，确保数值有效
        const heavyUser = Math.max(0, Number(this.dashboardData.tagDistribution?.heavyUser) || 0);
        const loyalUser = Math.max(0, Number(this.dashboardData.tagDistribution?.loyalUser) || 0);
        const broadbandUser = Math.max(0, Number(this.dashboardData.tagDistribution?.broadbandUser) || 0);
        const regularUser = Math.max(0, Number(this.dashboardData.tagDistribution?.regularUser) || 0);

        // 检查数据是否全部为0
        const hasData = heavyUser > 0 || loyalUser > 0 || broadbandUser > 0 || regularUser > 0;
        
        // 如果没有数据，设置默认值
        const displayHeavyUser = hasData ? heavyUser : 1500;
        const displayLoyalUser = hasData ? loyalUser : 2500;
        const displayBroadbandUser = hasData ? broadbandUser : 3000;
        const displayRegularUser = hasData ? regularUser : 5000;

        // 定义渐变色
        const heavyUserColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#ff6b6b' },
          { offset: 1, color: '#ee5a6f' }
        ]);
        const loyalUserColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#48dbfb' },
          { offset: 1, color: '#0abde3' }
        ]);
        const broadbandUserColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#54a0ff' },
          { offset: 1, color: '#0984e3' }
        ]);
        const regularUserColor = new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: '#a29bfe' },
          { offset: 1, color: '#6c5ce7' }
        ]);
        const noDataColor = '#dcdfe6'; // 无数据时的颜色

        // 准备数据项，根据是否有数据决定颜色
        const dataItems = [
          {
            value: displayHeavyUser,
            name: '重度用户',
            itemStyle: {
              color: hasData ? heavyUserColor : noDataColor
            },
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowColor: hasData ? 'rgba(255, 107, 107, 0.5)' : 'rgba(220, 223, 230, 0.5)'
              }
            }
          },
          {
            value: displayLoyalUser,
            name: '忠诚用户',
            itemStyle: {
              color: hasData ? loyalUserColor : noDataColor
            },
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowColor: hasData ? 'rgba(72, 219, 251, 0.5)' : 'rgba(220, 223, 230, 0.5)'
              }
            }
          },
          {
            value: displayBroadbandUser,
            name: '宽带用户',
            itemStyle: {
              color: hasData ? broadbandUserColor : noDataColor
            },
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowColor: hasData ? 'rgba(84, 160, 255, 0.5)' : 'rgba(220, 223, 230, 0.5)'
              }
            }
          },
          {
            value: displayRegularUser,
            name: '普通用户',
            itemStyle: {
              color: hasData ? regularUserColor : noDataColor
            },
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowColor: hasData ? 'rgba(162, 155, 254, 0.5)' : 'rgba(220, 223, 230, 0.5)'
              }
            }
          }
        ];

        const option = {
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'shadow'
            },
            formatter: function(params) {
              let result = `${params[0].name}<br/>`;
              params.forEach(item => {
                const dataSource = hasData ? '实际数据' : '示例数据';
                result += `${item.marker} ${item.seriesName}: ${item.value} (${dataSource})<br/>`;
              });
              return result;
            },
            backgroundColor: 'rgba(0, 0, 0, 0.8)',
            borderColor: '#666',
            textStyle: { color: '#fff' }
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            containLabel: true
          },
          xAxis: [
            {
              type: 'category',
              data: ['重度用户', '忠诚用户', '宽带用户', '普通用户'],
              axisTick: {
                alignWithLabel: true
              },
              axisLabel: {
                color: '#666',
                fontSize: 12
              },
              axisLine: {
                lineStyle: {
                  color: '#e0e0e0'
                }
              }
            }
          ],
          yAxis: [
            {
              type: 'value',
              name: '用户数',
              nameTextStyle: {
                color: '#666'
              },
              axisLabel: {
                color: '#666',
                fontSize: 12,
                formatter: function(value) {
                  if (value >= 10000) {
                    return (value / 10000) + '万';
                  }
                  return value;
                }
              },
              axisLine: {
                lineStyle: {
                  color: '#e0e0e0'
                }
              },
              splitLine: {
                lineStyle: {
                  color: '#f0f0f0',
                  type: 'dashed'
                }
              }
            }
          ],
          series: [
            {
              name: '用户数',
              type: 'bar',
              barWidth: '60%',
              data: dataItems,
              // 添加动画配置
              animationDuration: 1000,
              animationEasing: 'cubicOut',
              animationDelay: function(idx) {
                return idx * 100;
              },
              // 添加标记，显示最大值
              markPoint: {
                data: [
                  { type: 'max', name: '最大值', symbol: 'pin', symbolSize: 40 }
                ],
                label: {
                  formatter: '{b}: {c}',
                  color: '#333'
                }
              }
            }
          ]
        };

        // 如果没有数据，添加提示文本
        if (!hasData) {
          option.title = {
            text: '暂无数据，显示示例数据',
            left: 'center',
            top: 10,
            textStyle: {
              color: '#909399',
              fontSize: 12
            }
          };
        }

        chart.setOption(option);
      } catch (error) {
        console.error('初始化标签分布图表失败:', error);
      }
    },

    /** 初始化渗透率图表 */
    initPenetrationChart() {
      try {
        const chartDom = document.getElementById('penetrationChart');
        if (!chartDom) {
          console.warn('渗透率图表容器未找到');
          return;
        }
        
        const chart = echarts.init(chartDom);
        this.charts.penetration = chart;
        
        // 使用后端提供的渗透率数据或默认值
        const penetrationData = this.dashboardData.penetrationRates || {};
        
        // 数据验证和格式化，确保数值有效且在合理范围内
        const validateAndConstrain = (value, defaultValue) => {
          const numValue = Number(value) || defaultValue;
          return Math.max(0, Math.min(100, numValue)); // 确保在0-100%范围内
        };
        
        // 定义服务数据，包含默认值和颜色
        const services = [
          { name: '宽带服务', value: validateAndConstrain(penetrationData.broadband, 65), color: '#48dbfb' },
          { name: '重度用户', value: validateAndConstrain(penetrationData.heavyUser, 45), color: '#ff6b6b' },
          { name: '忠诚用户', value: validateAndConstrain(penetrationData.loyalUser, 30), color: '#1dd1a1' },
          { name: '电视服务', value: validateAndConstrain(penetrationData.tvService, 85), color: '#54a0ff' },
          { name: '互动业务', value: validateAndConstrain(penetrationData.interactiveBusiness, 45), color: '#feca57' },
          { name: '增值服务', value: validateAndConstrain(penetrationData.valueAddedService, 30), color: '#ff9ff3' }
        ];
        
        // 检查是否有实际数据（除了默认值）
        const hasActualData = !!Object.keys(penetrationData).length;
        
        // 计算趋势线数据（模拟增长率）
        const trendData = services.map(service => ({
          name: service.name,
          value: service.value + (Math.random() > 0.5 ? 5 : -3) // 模拟5%增长或3%下降
        }));
        
        // 定义渐变色生成函数
        const createGradient = (color) => {
          return new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            {offset: 0, color: color},
            {offset: 1, color: color + '80'}
          ]);
        };
        
        // 准备基础配置
        const option = {
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'cross'
            },
            backgroundColor: 'rgba(0, 0, 0, 0.8)',
            borderColor: '#666',
            textStyle: { color: '#fff' },
            formatter: function(params) {
              let result = `${params[0].name}<br/>`;
              params.forEach(p => {
                const dataSource = hasActualData ? '实际数据' : '示例数据';
                result += `${p.seriesName}: ${p.value}% (${dataSource})<br/>`;
              });
              const trend = trendData.find(t => t.name === params[0].name);
              if (trend) {
                const change = trend.value - params[0].value;
                result += `趋势预测: ${change > 0 ? '+' : ''}${change.toFixed(1)}%`;
              }
              return result;
            }
          },
          legend: {
            data: ['当前渗透率', '趋势预测'],
            top: 10,
            textStyle: {
              color: '#666',
              fontSize: 12
            }
          },
          grid: {
            left: '3%',
            right: '4%',
            bottom: '3%',
            top: '15%',
            containLabel: true
          },
          xAxis: {
            type: 'category',
            data: services.map(s => s.name),
            axisLabel: {
              color: '#666',
              interval: 0,
              rotate: 0,
              fontSize: 10
            },
            axisLine: {
              lineStyle: {
                color: '#e5e5e5'
              }
            }
          },
          yAxis: {
            type: 'value',
            max: 100,
            axisLabel: {
              color: '#666',
              formatter: '{value}%',
              fontSize: 12
            },
            axisLine: {
              show: false
            },
            splitLine: {
              lineStyle: {
                color: '#f0f0f0',
                type: 'dashed'
              }
            }
          },
          series: [
            {
              name: '当前渗透率',
              type: 'bar',
              data: services.map(service => ({
                value: service.value,
                itemStyle: {
                  color: createGradient(service.color),
                  borderRadius: [4, 4, 0, 0]
                }
              })),
              barWidth: '40%',
              label: {
                show: true,
                position: 'top',
                color: '#666',
                fontSize: 10,
                formatter: '{c}%'
              },
              // 添加动画配置
              animationDuration: 1000,
              animationEasing: 'cubicOut',
              animationDelay: function(idx) {
                return idx * 100;
              }
            },
            {
              name: '趋势预测',
              type: 'line',
              data: trendData.map(t => t.value),
              smooth: true,
              symbol: 'circle',
              symbolSize: 6,
              lineStyle: {
                color: '#5f27cd',
                width: 2
              },
              itemStyle: {
                color: '#5f27cd',
                borderColor: '#fff',
                borderWidth: 2
              },
              areaStyle: {
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {offset: 0, color: 'rgba(95, 39, 205, 0.3)'},
                  {offset: 1, color: 'rgba(95, 39, 205, 0.05)'}
                ])
              },
              // 添加动画配置
              animationDuration: 1500,
              animationEasing: 'cubicOut'
            }
          ]
        };
        
        // 如果没有实际数据，添加提示文本
        if (!hasActualData) {
          option.title = {
            text: '暂无实际数据，显示示例数据',
            left: 'center',
            top: 10,
            textStyle: {
              color: '#909399',
              fontSize: 12
            }
          };
        }
        
        chart.setOption(option);
      } catch (error) {
        console.error('初始化渗透率图表失败:', error);
      }
    },

    /** 初始化品牌分布图表 */
    initBrandChart() {
      try {
        const chartDom = document.getElementById('brandChart');
        if (!chartDom) {
          console.warn('品牌分布图表容器未找到');
          return;
        }
        
        const chart = echarts.init(chartDom);
        this.charts.brand = chart;
        
        // 使用后端提供的品牌分布数据或默认值
        const brandData = this.dashboardData.brandDistribution || {};
        
        // 数据验证和格式化
        const validateNumber = (value, defaultValue) => {
          return Math.max(0, Number(value) || defaultValue);
        };
        
        // 检查是否有实际数据（除了默认值）
        const hasActualData = !!Object.keys(brandData).length;
        
        // 定义品牌数据和颜色（使用辅助函数创建渐变色）
        const createGradient = (color1, color2) => {
          return new echarts.graphic.LinearGradient(0, 0, 1, 1, [
            {offset: 0, color: color1},
            {offset: 1, color: color2}
          ]);
        };
        
        // 品牌颜色映射
        const brandColors = {
          cableTv: createGradient('#54a0ff', '#1890ff'),
          iptv: createGradient('#fa8c16', '#fa541c'),
          ott: createGradient('#13c2c2', '#52c41a'),
          others: createGradient('#722ed1', '#eb2f96')
        };
        
        // 准备数据，应用数据验证
        const data = [
          { 
            name: '有线电视', 
            value: validateNumber(brandData.cableTv, 45), 
            itemStyle: { color: brandColors.cableTv }
          },
          { 
            name: 'IPTV', 
            value: validateNumber(brandData.iptv, 30), 
            itemStyle: { color: brandColors.iptv }
          },
          { 
            name: 'OTT', 
            value: validateNumber(brandData.ott, 15), 
            itemStyle: { color: brandColors.ott }
          },
          { 
            name: '其他', 
            value: validateNumber(brandData.others, 10), 
            itemStyle: { color: brandColors.others }
          }
        ];
        
        // 计算总数，用于计算百分比和用户数
        const totalValue = data.reduce((sum, item) => sum + item.value, 0);
        
        // 基础配置
        const option = {
          tooltip: {
            trigger: 'item',
            backgroundColor: 'rgba(0, 0, 0, 0.8)',
            borderColor: '#666',
            textStyle: { color: '#fff' },
            formatter: function(params) {
              const dataSource = hasActualData ? '实际数据' : '示例数据';
              const usersValue = Math.round((params.value / totalValue) * (this.dashboardData.totalUsers || 10000));
              return `${params.seriesName}<br/>${params.name}: ${params.value}<br/>占比: ${params.percent}%<br/>用户数: ${usersValue}<br/>(${dataSource})`;
            }.bind(this)
          },
          legend: {
            orient: 'horizontal',
            bottom: 10,
            left: 'center',
            textStyle: {
              color: '#666',
              fontSize: 12
            }
          },
          series: [
            {
              name: '服务品牌分布',
              type: 'pie',
              radius: ['40%', '75%'],
              center: ['50%', '45%'],
              avoidLabelOverlap: false,
              itemStyle: {
                borderRadius: 8,
                borderColor: '#fff',
                borderWidth: 2,
                shadowBlur: 8,
                shadowColor: 'rgba(0, 0, 0, 0.1)'
              },
              label: {
                show: false,
                position: 'center'
              },
              emphasis: {
                label: {
                  show: true,
                  fontSize: '18',
                  fontWeight: 'bold',
                  color: '#333'
                },
                itemStyle: {
                  shadowBlur: 20,
                  shadowOffsetX: 0,
                  shadowColor: 'rgba(0, 0, 0, 0.3)'
                },
                scale: true,
                scaleSize: 10
              },
              labelLine: {
                show: false
              },
              data: data,
              // 添加动画配置
              animationDuration: 1500,
              animationEasing: 'cubicOut',
              animationDelay: function(idx) {
                return idx * 200;
              }
            }
          ]
        };
        
        // 如果没有实际数据，添加提示文本
        if (!hasActualData) {
          option.title = {
            text: '暂无实际数据，显示示例数据',
            left: 'center',
            top: 10,
            textStyle: {
              color: '#909399',
              fontSize: 12
            }
          };
        }
        
        chart.setOption(option);
      } catch (error) {
        console.error('初始化品牌分布图表失败:', error);
      }
    },

    /**
     * 使用动画更新图表数据
     */
    updateChartsWithAnimation(oldData) {
      // 更新消费分布图表
      if (this.charts.consumption) {
        this.charts.consumption.setOption({
          series: [{
            data: [
              { value: this.dashboardData.highTvConsumption || 0, name: '高消费' },
              { value: this.dashboardData.mediumTvConsumption || 0, name: '中消费' },
              { value: this.dashboardData.lowTvConsumption || 0, name: '低消费' }
            ]
          }]
        });
      }

      // 更新标签分布图表
      if (this.charts.tagDistribution) {
        const tagData = this.dashboardData.tagDistribution || {
          heavyUser: this.dashboardData.heavyUsers || 0,
          loyalUser: this.dashboardData.loyalUsers || 0,
          broadbandUser: this.dashboardData.broadbandUsers || 0,
          regularUser: (this.dashboardData.totalUsers || 0) - 
                       (this.dashboardData.heavyUsers || 0) - 
                       (this.dashboardData.loyalUsers || 0) - 
                       (this.dashboardData.broadbandUsers || 0)
        };
        
        const tagValues = [tagData.heavyUser, tagData.loyalUser, tagData.broadbandUser, tagData.regularUser];
        const tagColors = ['#ff6b6b', '#48dbfb', '#1dd1a1', '#5f27cd'];
        
        this.charts.tagDistribution.setOption({
          series: [{
            data: tagValues.map((value, index) => ({
              value: value,
              itemStyle: {
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {offset: 0, color: tagColors[index]},
                  {offset: 1, color: tagColors[index] + '80'}
                ])
              }
            }))
          }]
        });
      }
      
      // 更新渗透率图表
      if (this.charts.penetration) {
        const penetrationData = this.dashboardData.penetrationRates || {
          broadband: 65,
          heavyUser: 45,
          loyalUser: 30
        };
        
        const currentData = [
          penetrationData.broadband,
          penetrationData.heavyUser,
          penetrationData.loyalUser,
          85,
          45,
          30
        ];
        
        // 模拟趋势数据
        const trendData = currentData.map(value => value + (Math.random() > 0.5 ? 5 : -3));
        
        this.charts.penetration.setOption({
          series: [
            {
              name: '当前渗透率',
              data: currentData.map((value, index) => ({
                value: value,
                itemStyle: {
                  color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                    {offset: 0, color: ['#48dbfb', '#ff6b6b', '#1dd1a1', '#54a0ff', '#feca57', '#ff9ff3'][index]},
                    {offset: 1, color: ['#48dbfb', '#ff6b6b', '#1dd1a1', '#54a0ff', '#feca57', '#ff9ff3'][index] + '80'}
                  ])
                }
              }))
            },
            {
              name: '趋势预测',
              data: trendData
            }
          ]
        });
      }
      
      // 更新品牌分布图表
      if (this.charts.brand) {
        const brandData = this.dashboardData.brandDistribution || {
          cableTv: 45,
          iptv: 30,
          others: 25
        };
        
        const data = [
          { name: '有线电视', value: brandData.cableTv || 45 },
          { name: 'IPTV', value: brandData.iptv || 30 },
          { name: 'OTT', value: brandData.ott || 15 },
          { name: '其他', value: brandData.others || 10 }
        ];
        
        this.charts.brand.setOption({
          series: [{
            data: data
          }]
        });
      }
      
      // 为数据变化添加动画效果
      this.animateMetricChanges(oldData);
    },
    
    /**
     * 为指标变化添加动画效果
     */
    animateMetricChanges(oldData) {
      const metricElements = {
        totalUsers: '.total-users .metric-value',
        heavyUsers: '.heavy-users .metric-value',
        loyalUsers: '.loyal-users .metric-value',
        broadbandUsers: '.broadband-users .metric-value'
      };
      
      Object.entries(metricElements).forEach(([key, selector]) => {
        const oldValue = oldData[key] || 0;
        const newValue = this.dashboardData[key] || 0;
        
        if (oldValue !== newValue) {
          // 找到对应的DOM元素并添加动画效果
          const element = document.querySelector(selector);
          if (element) {
            element.classList.add('data-changed');
            setTimeout(() => {
              element.classList.remove('data-changed');
            }, 1000);
          }
        }
      });
    },

    /** 处理窗口大小变化 */
    handleResize() {
      Object.values(this.charts).forEach(chart => {
        if (chart && typeof chart.resize === 'function') {
          chart.resize();
        }
      });
    },

    /** 获取消费水平对应的标签类型 */
    getConsumptionLevelType(level) {
      const typeMap = {
        '高': 'danger',
        '中': 'warning',
        '低': 'info'
      };
      return typeMap[level] || 'info';
    }
  }
};
</script>

<style scoped>
.app-container {
  padding: 20px;
}

.header-section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
  padding-bottom: 15px;
  border-bottom: 1px solid #f0f0f0;
}

.header-left {
  display: flex;
  flex-direction: column;
}

.header-section h2 {
  margin: 0 0 5px 0;
  color: #303133;
  font-size: 20px;
}

.last-refresh-time {
  font-size: 12px;
  color: #909399;
}

.header-right {
  display: flex;
  align-items: center;
}

@media (max-width: 768px) {
  .header-section {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .header-right {
    margin-top: 15px;
    flex-wrap: wrap;
    width: 100%;
  }
  
  .header-right .el-switch {
    margin-bottom: 10px;
    width: 100%;
  }
  
  .header-right .el-select {
    width: calc(100% - 120px);
    margin-right: 10px;
  }
  
  .header-right .el-button {
    width: 110px;
  }
}

.metrics-section {
  margin-bottom: 20px;
}

.metric-card {
  background: #fff;
  border-radius: 8px;
  padding: 20px;
  display: flex;
  align-items: center;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease;
}

.metric-card:hover {
  transform: translateY(-2px);
}

.metric-icon {
  font-size: 32px;
  margin-right: 16px;
  width: 50px;
  height: 50px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
}

.total-users .metric-icon {
  background: #e6f7ff;
  color: #1890ff;
}

.heavy-users .metric-icon {
  background: #fff7e6;
  color: #fa8c16;
}

.loyal-users .metric-icon {
  background: #f6ffed;
  color: #52c41a;
}

.broadband-users .metric-icon {
  background: #f9f0ff;
  color: #722ed1;
}

.metric-content {
  flex: 1;
}

.metric-value {
  font-size: 24px;
  font-weight: bold;
  color: #303133;
  margin-bottom: 4px;
  transition: all 0.3s ease;
}

/* 数据变化动画效果 */
.metric-value.data-changed {
  animation: pulse 1s ease;
  color: #409eff;
}

@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}

.metric-label {
  font-size: 14px;
  color: #606266;
}

.charts-section {
  margin-bottom: 20px;
}

.chart-card {
  background: #fff;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.chart-header {
  margin-bottom: 16px;
  border-bottom: 1px solid #f0f0f0;
  padding-bottom: 10px;
}

.chart-header h3 {
  margin: 0;
  font-size: 16px;
  color: #303133;
}

.chart-content {
  height: 300px;
}

.chart {
  width: 100%;
  height: 100%;
}

.recent-data-section {
  background: #fff;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}

.section-header {
  margin-bottom: 16px;
  border-bottom: 1px solid #f0f0f0;
  padding-bottom: 10px;
}

.section-header h3 {
  margin: 0;
  font-size: 16px;
  color: #303133;
}

.loading-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.8);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 9999;
}

.loading-mask p {
  margin-top: 10px;
  color: #606266;
}

@media (max-width: 1200px) {
  .chart-content {
    height: 300px;
  }
}

@media (max-width: 768px) {
  .header-section {
    flex-direction: column;
    align-items: flex-start;
  }
  
  .header-section h2 {
    margin-bottom: 10px;
    font-size: 18px;
  }
  
  .chart-content {
    height: 250px;
  }
  
  .metrics-section .el-col {
    margin-bottom: 15px;
  }
  
  .metric-value {
    font-size: 20px;
  }
  
  .metric-icon {
    font-size: 24px;
    width: 40px;
    height: 40px;
  }
  
  .recent-data-section {
    overflow-x: auto;
  }
  
  .chart-card .chart-header h3 {
    font-size: 14px;
  }
}

@media (max-width: 480px) {
  .app-container {
    padding: 10px;
  }
  
  .metric-card {
    padding: 15px;
  }
  
  .chart-content {
    height: 200px;
  }
  
  .chart-card {
    padding: 15px 10px;
  }
  
  .header-right {
    flex-direction: column;
    align-items: flex-start;
    width: 100%;
  }
  
  .header-right .el-switch {
    width: 100%;
    margin-bottom: 10px;
    margin-right: 0 !important;
  }
  
  .header-right .el-select {
    width: 100%;
    margin-right: 0 !important;
    margin-bottom: 10px;
  }
  
  .header-right .el-button {
    width: 100%;
  }
}
</style>